using System;
using System.Windows.Forms;

namespace SkypeControl
{
    internal partial class SkypeClient : Form
    {
        public SkypeClient()
        {
            this.InitializeComponent();

            UM_SkypeControlAPIDiscover = Platform.RegisterWindowMessage(Constants.SkypeControlAPIDiscover);
            UM_SkypeControlAPIAttach = Platform.RegisterWindowMessage(Constants.SkypeControlAPIAttach);

            CreateHandle();
        }

        public bool Connect()
        {
            IntPtr result;
            IntPtr aRetVal = Platform.SendMessageTimeout(Platform.HWND_BROADCAST, UM_SkypeControlAPIDiscover, Handle, IntPtr.Zero, Platform.SendMessageTimeoutFlags.SMTO_NORMAL, 100, out result);

            return aRetVal != IntPtr.Zero;
        }

        public void Disconnect()
        {
            this.Command(string.Empty);
            this.mySkypeHandle = IntPtr.Zero;
        }

        public delegate bool CommandHandler(string theCommand);

        public bool Command(string theCommand)
        {
            if (this.InvokeRequired)
            {
                return (bool)this.Invoke(new CommandHandler(this.Command), theCommand);
            }
            else
            {
                Platform.CopyDataStruct aCDS = new Platform.CopyDataStruct();

                aCDS.ID = "1";
                aCDS.Data = theCommand;
                aCDS.Length = aCDS.Data.Length + 1;

                IntPtr result;
                IntPtr aRetVal = Platform.SendMessageTimeout(this.mySkypeHandle, Platform.WM_COPYDATA, Handle, ref aCDS, Platform.SendMessageTimeoutFlags.SMTO_NORMAL, 100, out result);

                return aRetVal != IntPtr.Zero;
            }
        }

        private uint UM_SkypeControlAPIDiscover = 0;
        private uint UM_SkypeControlAPIAttach = 0;

        private IntPtr mySkypeHandle = IntPtr.Zero;

        public event SkypeAttachHandler SkypeAttach;
        public event SkypeResponseHandler SkypeResponse;

        protected override void WndProc(ref Message m)
        {
            uint aMsg = (uint)m.Msg;

            if (aMsg == UM_SkypeControlAPIAttach)
            {
                SkypeAttachStatus anAttachStatus = (SkypeAttachStatus)m.LParam;

                if (anAttachStatus == SkypeAttachStatus.Success)
                {
                    this.mySkypeHandle = m.WParam;
                }

                if (this.SkypeAttach != null)
                {
                    this.SkypeAttach(this, new SkypeAttachEventArgs(anAttachStatus));
                }

                m.Result = new IntPtr(1);
                return;
            }

            if (aMsg == Platform.WM_COPYDATA)
            {
                if (m.WParam == this.mySkypeHandle)
                {
                    Platform.CopyDataStruct aCDS = (Platform.CopyDataStruct)m.GetLParam(typeof(Platform.CopyDataStruct));
                    string aResponse = aCDS.Data;

                    if (SkypeResponse != null)
                        this.SkypeResponse(this, new SkypeResponseEventArgs(aResponse));

                    m.Result = new IntPtr(1);
                    return;
                }
            }

            base.WndProc(ref m);
        }
    }
}